package com.itmake.sample.easyexcel.convert;

import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;

import java.math.BigDecimal;
import java.util.Map;

/**
 * 类型转换
 *
 * @param <T>
 * @author Amjacks
 * @since 2023/08/10
 */
public abstract class ExcelConvert<T, V> implements Converter<T> {

    private final Class<T> keyClass;

    private final Class<V> valClass;

    /**
     * 储存转换，eg：{java值: 表格值, java值: 表格值}
     */
    private Map<T, V> map;

    protected ExcelConvert(Map<T, V> map, Class<T> keyClass, Class<V> valClass) {
        this.map = map;
        this.keyClass = keyClass;
        this.valClass = valClass;
    }

    @Override
    public Class<?> supportJavaTypeKey() {
        return keyClass;
    }

    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        CellDataTypeEnum typeEnum = null;
        // String、Boolean、Number
        if (valClass.isAssignableFrom(String.class)) {
            typeEnum = CellDataTypeEnum.STRING;
        } else if (valClass.isAssignableFrom(Boolean.class)) {
            typeEnum = CellDataTypeEnum.BOOLEAN;
        } else if (valClass.isAssignableFrom(Number.class)) {
            typeEnum = CellDataTypeEnum.NUMBER;
        }
        return typeEnum;
    }

    @Override
    public T convertToJavaData(ReadCellData cellData,
                               ExcelContentProperty contentProperty,
                               GlobalConfiguration globalConfiguration) {
        V val = null;
        // String、Boolean、Number
        if (valClass.isAssignableFrom(String.class)) {
            val = valClass.cast(cellData.getStringValue());
        } else if (valClass.isAssignableFrom(Boolean.class)) {
            val = valClass.cast(cellData.getBooleanValue());
        } else if (valClass.isAssignableFrom(Number.class)) {
            val = valClass.cast(cellData.getNumberValue());
        }
        // 获取 key
        T key = null;
        for (Map.Entry<T, V> entry : map.entrySet()) {
            if (entry.getValue().equals(val)) {
                key = entry.getKey();
                break;
            }
        }
        return key;
    }

    @Override
    public WriteCellData<?> convertToExcelData(T value,
                                               ExcelContentProperty contentProperty,
                                               GlobalConfiguration globalConfiguration) {
        WriteCellData<?> data = null;
        V v = map.get(value);
        // String、Boolean、Number
        if (valClass.isAssignableFrom(String.class)) {
            data = new WriteCellData<>((String) v);
        } else if (valClass.isAssignableFrom(Boolean.class)) {
            data = new WriteCellData<>((Boolean) v);
        } else if (valClass.isAssignableFrom(Number.class)) {
            data = new WriteCellData<>((BigDecimal) v);
        }
        return data;
    }
}
